﻿using AutoMapper;
using InitQ.Cache;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using SkiaSharp;
using Smart.Admin.Domain.Common;
using Smart.Admin.Domain.Model.Config;
using Smart.Admin.Domain.Model.Const;
using Smart.Admin.Domain.Model.Entity;
using Smart.Admin.Domain.Model.Enum;
using Smart.Admin.Domain.Model.Request.Account;
using Smart.Admin.Domain.Model.Request.Department;
using Smart.Admin.Domain.Model.Response;
using Smart.Admin.Domain.Model.Response.Account;
using Smart.Admin.Domain.Model.Response.Department;
using Smart.Admin.Domain.Model.Response.Menu;
using Smart.Admin.Domain.Repository;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace Smart.Admin.Domain.Service
{
    /// <summary>
    /// 部门服务
    /// </summary>
    public class DepartmentService
    {
        private readonly SmartAdminDbContext _context;
        private readonly ICacheService _redisService;
        private readonly IOptions<JwtOptions> _options;
        private readonly IMapper _mapper;
        public DepartmentService(SmartAdminDbContext context, ICacheService redisService, IOptions<JwtOptions> options, IMapper mapper)
        {
            _context = context;
            _redisService = redisService;
            _options = options;
            _mapper = mapper;
        }

        /// <summary>
        /// 获取部门
        /// </summary>
        /// <returns></returns>
        public async Task<JsonResponse<List<DepartmentResponse>>> GetAllDepartment() 
        {
            try
            {
                var query = from department in _context.Department
                            join employee in _context.Employee on department.ManagerId equals employee.Id
                            orderby department.Sort descending
                            select new DepartmentResponse()
                            {
                                DepartmentId = department.Id,
                                CreateTime = department.CreateTime,
                                ManagerId = department.ManagerId,
                                ManagerName = employee.Name,
                                Name = department.Name,
                                ParentId = department.ParentId,
                                Sort = department.Sort,
                                UpdateTime = department.UpdateTime,
                            };
                var list = await query.ToListAsync();
                return JsonResult.Success(list);
            }
            catch (Exception ex)
            {
                return JsonResult.Error<List<DepartmentResponse>>(message:"系统错误");
            }
        }

        /// <summary>
        /// 获取部门(树形结构)
        /// </summary>
        /// <returns></returns>
        public async Task<JsonResponse<List<TreeDepartmentResponse>>> GetTreeDepartment()
        {
            try
            {
                var query = from department in _context.Department
                            join employee in _context.Employee on department.ManagerId equals employee.Id
                            orderby department.Sort descending
                            select new TreeDepartmentResponse()
                            {
                                DepartmentId = department.Id,
                                CreateTime = department.CreateTime,
                                ManagerId = department.ManagerId,
                                ManagerName = employee.Name,
                                Name = department.Name,
                                ParentId = department.ParentId,
                                Sort = department.Sort,
                            };
                var list = await query.ToListAsync();
                var response = list.Where(m=>m.ParentId==0).ToList()??new List<TreeDepartmentResponse>();
                for (int i = 0; i < response.Count; i++) 
                {
                    response[i] = BuildTreeDepartment(list, response[i]);
                }    
                return JsonResult.Success(response);
            }
            catch (Exception ex)
            {
                return JsonResult.Error<List<TreeDepartmentResponse>>(message: "系统错误");
            }
        }

        /// <summary>
        /// 创建部门
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<JsonResponse> CreateDepartment(CreateDepartmentRequest request) 
        {
            try
            {
                var bl = await _context.Department.AnyAsync(m => m.Name == request.Name);
                if (bl) return JsonResult.Error(message:"部门名称已存在");
                var model = _mapper.Map<DepartmentEntity>(request);
                model.CreateTime = DateTime.Now;
                model.UpdateTime = model.CreateTime;
                await _context.Department.AddAsync(model);
                await _context.SaveChangesAsync();
                return JsonResult.Success();
            }
            catch (Exception ex)
            {
                return JsonResult.Error(message: "系统错误");
            }
        }


        /// <summary>
        /// 修改部门
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<JsonResponse> UpdateDepartment(UpdateDepartmentRequest request)
        {
            try
            {
                var model = await _context.Department.FirstOrDefaultAsync(m => m.Id == request.DepartmentId);
                if (model == null) return JsonResult.Error(message:"数据不存在");
                var bl = await _context.Department.AnyAsync(m => m.Name == request.Name && m.Id != request.DepartmentId);
                if (bl) return JsonResult.Error(message:"部门名称已存在");
                if(model.ParentId==0 && request.ParentId !=0) return JsonResult.Error(message:"顶级部门,不允许修改上级部门");

                model.ParentId = request.ParentId;
                model.Name = request.Name;
                model.Sort = request.Sort;
                model.ManagerId = request.ManagerId;
                model.UpdateTime = DateTime.Now;
                _context.Department.Update(model);
                await _context.SaveChangesAsync();
                return JsonResult.Success();
            }
            catch (Exception ex)
            {
                return JsonResult.Error(message: "系统错误");
            }
        }

        /// <summary>
        /// 删除部门
        /// </summary>
        /// <param name="departmentId"></param>
        /// <returns></returns>
        public async Task<JsonResponse> DeleteDepartment(long departmentId) 
        {
            try
            {
                var model = await _context.Department.FirstOrDefaultAsync(m => m.Id == departmentId);
                if(model != null) 
                {
                    //判断是否存在下级部门
                    var bl = await _context.Department.AnyAsync(m=>m.ParentId == departmentId);
                    if (bl) return JsonResult.Error(message:"请先删除子部门");
                    _context.Department.Remove(model);
                    await _context.SaveChangesAsync();
                }
                return JsonResult.Success();
            }
            catch (Exception ex)
            {
                return JsonResult.Error(message:"系统错误");
            }
        }

        /// <summary>
        /// 递归构建部门
        /// </summary>
        /// <param name="list"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        private TreeDepartmentResponse BuildTreeDepartment(List<TreeDepartmentResponse> list, TreeDepartmentResponse model) 
        {
            model.Children = list.Where(m => m.ParentId == model.DepartmentId).OrderByDescending(p=>p.Sort).ToList();
            if (model.Children != null && model.Children.Count() != 0)
            {
                for (int i = 0; i < model.Children.Count(); i++)
                {
                    var child = model.Children[i];
                    child = BuildTreeDepartment(list, child);
                }
            }
            return model;
        }
    }
}
